﻿// -------------------------------------------------------------------------
//    @FileName         :    NFTransGetRoleList.cpp
//    @Author           :    gaoyi
//    @Date             :    24-8-13
//    @Email            :    445267987@qq.com
//    @Module           :    NFTransGetRoleList
//
// -------------------------------------------------------------------------

#include "NFTransGetRoleList.h"
#include <NFLogicCommon/NFScopedMessageHead.h>
#include <NFServerComm/NFServerCommon/NFIServerMessageModule.h>

#include <NFLogicConfig.h>
#include <NFPacketSendUtil.h>
#include <NFRegisterCache.h>
#include <NFPlayer.h>

#include "NFHealthGameUtil.h"
#include "NFOnlineService.h"
#include "NFSession.h"
#include "NFSessionUtil.h"
#include "NFTransGetAcc.h"
#include "proto_cs_cmd.nanopb.h"
#include "proto_svr_common.nanopb.h"
#include "proto_svr_onlinesvr.pb.h"
#include "NFLogicCommon/NFVersion.h"

typedef enum
{
    EN_TGRL_INIT = 0,
    EN_TGRL_GET_ROLELIST = 1,
    EN_TGRL_TRY_ACCLOGIN = 2,
    EN_TGRL_FIN_OK = 3,
} ETransGetRoleListState;

NFTransGetRoleList::NFTransGetRoleList()
{
    if (EN_OBJ_MODE_INIT == NFShmMgr::Instance()->GetCreateMode())
    {
        CreateInit();
    }
    else
    {
        ResumeInit();
    }
}

NFTransGetRoleList::~NFTransGetRoleList()
{
}

int NFTransGetRoleList::CreateInit()
{
    return 0;
}

int NFTransGetRoleList::ResumeInit()
{
    return 0;
}

int NFTransGetRoleList::HandleCSMsgReq(const google::protobuf::Message* pReq)
{
    const proto_ff::Proto_CSLoginReq* pCSMsgReq = dynamic_cast<const proto_ff::Proto_CSLoginReq*>(pReq);
    CHECK_NULL(0, pCSMsgReq);

    NFSession* pSession = GetClientSession();
    CHECK_EXPR(pSession, -3, "GetClientSession Failed TransInfo:{}", DebugString());

    pSession->Login(pCSMsgReq);

    proto_ff::tbRoleList tbRoleList;
    tbRoleList.set_uin(m_uin);
    tbRoleList.set_world_id(m_zoneId);
    tbRoleList.set_world_type(pSession->GetPlatformType());
    GetCacheDataSingleReq<NFTransGetAcc>(m_uin, 0, tbRoleList, E_TABLE_ROLE_LIST);
    SetState(EN_TGRL_GET_ROLELIST);
    return 0;
}

int NFTransGetRoleList::GetCacheDataRes(int ullId, int iTableId, int iReason, int32_t errCode, google::protobuf::Message* pMessage)
{
    CHECK_EXPR(GetState() == EN_TGRL_GET_ROLELIST, proto_ff::ERR_CODE_SYSTEM_OBJSTATUS_INVALID, "invalid tran state! {}", DebugString());

    NFSession* pSession = GetClientSession();
    CHECK_EXPR(pSession, -3, "GetClientSession Failed TransInfo:{}", DebugString());

    if (errCode == ERR_CODE_STORESVR_ERRCODE_SELECT_EMPTY)
    {
        bool bCanRegister;
        int iRetCode = NFSessionUtil::IsRegisterLimit(pSession, bCanRegister);
        CHECK_ERR(m_iClientSessionID, iRetCode, "IsRegisterLimit failed, TransInfo:{}", DebugString());
        if (!bCanRegister)
        {
            return ERR_CODE_FORBID_REGIST_ACCOUNT;
        }
    }
    else if (errCode != 0)
    {
        LOG_ERR(ullId, errCode, "GetCacheDataRes failed, errCode: {}", errCode);
        return errCode;
    }

    NFOnlineService::TryAccOnlineReq(pSession, GetGlobalId());
    pSession->SetLoginQueue(true);
    SetState(EN_TGRL_TRY_ACCLOGIN);
    return 0;
}

int NFTransGetRoleList::OnAccLoginSuccess(const proto_ff::Proto_OnLine2ZoneLoginRes& res)
{
    NFSession* pSession = GetClientSession();
    CHECK_EXPR(pSession, -3, "GetClientSession Failed TransInfo:{}", DebugString());

    NFScopedMessageHead scopedMessageHead(GetClientSessionID(), m_stCSMsgHeadReq.m_iMsgID, GetClientRequestSeq());
    NotifyClientRoleList(pSession, res, 0);

    SetFinished(0);
    SetState(EN_TGRL_FIN_OK);
    return 0;
}

int NFTransGetRoleList::OnTransFinished(int iRunLogicRetCode)
{
    if (iRunLogicRetCode > 0)
    {
        if (GetClientSession())
        {
            NFPacketSendUtil::SendErrToClient(GetClientSession(), proto_ff::E_CS_LOGIN_REQ, (proto_ff::Proto_CS_ErrorCode)iRunLogicRetCode);
        }
    }

    return 0;
}

int NFTransGetRoleList::HandleDispSvrRes(uint32_t nMsgId, const NFDataPackage& packet, uint32_t reqTransId, uint32_t rspTransId)
{
    int iRetCode = 0;
    if (nMsgId == E_ONLINE2ZONE_LOGIN_RES)
    {
        iRetCode = OnHandleAccLoginRes(nMsgId, packet, reqTransId, rspTransId);
        CHECK_ERR(m_uin, iRetCode, "OnHandleAccLoginRes failed, TransInfo:{}", DebugString());
    }
    else
    {
        LOG_ERR(m_uin, -1, "HandleDispSvrRes failed, unknown msgId: {}, TransInfo:{}", nMsgId, DebugString());
        return -1;
    }

    SetFinished(0);
    return 0;
}

int NFTransGetRoleList::OnHandleAccLoginRes(uint32_t nMsgId, const NFDataPackage& packet, uint32_t reqTransId, uint32_t rspTransId)
{
    proto_ff::Proto_OnLine2ZoneLoginRes res;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, res);
    CHECK_EXPR(GetState() == EN_TGRL_TRY_ACCLOGIN, proto_ff::ERR_CODE_SYSTEM_OBJSTATUS_INVALID, "invalid tran state! {}", DebugString());

    NFSession* pSession = GetClientSession();
    CHECK_NULL_WF(m_uin, pSession, "GetClientSession Failed TransInfo:{}", DebugString());
    pSession->SetLoginQueue(false);

    int iRetCode = 0;
    if (res.result() != 0)
    {
        return res.result();
    }
    else
    {
        if (res.role_list().role_data().sealed_time() > NF_ADJUST_TIMENOW())//还在封号时间内
        {
            NFHealthGameUtil::SendForbidLoginNtf(pSession, res.role_list().role_data().sealed_time());
        }
        else
        {
            iRetCode = OnAccLoginSuccess(res);
            CHECK_ERR(m_uin, iRetCode, "OnAccLoginSuccess failed, TransInfo:{}", DebugString());
        }
    }
    return 0;
}

int NFTransGetRoleList::NotifyClientRoleList(NFSession* pSession, const proto_ff::Proto_OnLine2ZoneLoginRes& res, uint64_t roleId)
{
    CHECK_NULL(0, pSession);
    auto pConfig = FindModule<NFIConfigModule>()->GetAppConfig(NF_ST_LOGIC_SERVER);
    CHECK_NULL(0, pConfig);

    proto_ff::Proto_CSRsp oCSRsp;
    proto_ff::Proto_CSLoginRes* pLoginRsp = oCSRsp.mutable_login();
    pLoginRsp->set_player_uin(pSession->GetUIN());
    pLoginRsp->set_role_id(roleId);
    pLoginRsp->set_server_time(NF_ADJUST_TIMENOW());
    pLoginRsp->set_server_version(GAMESVR_VERSION);
    pLoginRsp->set_excel_version(EXCEL_VERSION);
    pLoginRsp->set_mapdata_version(MAPDATA_VERSION);
    pLoginRsp->set_zoneid(pSession->GetZoneAreaID());

    pLoginRsp->set_server_open_time(pConfig->GetServerOpenTime());

    for (int i = 0; i < res.role_list().role_data().role_list_size(); i++)
    {
        proto_ff::RoleOne* pRoleOne = pLoginRsp->add_role_list();
        CHECK_NULL(0, pRoleOne);

        pRoleOne->CopyFrom(res.role_list().role_data().role_list(i));
    }

    for (int i = 0; i < res.online_role_list_size(); ++i)
    {
        pLoginRsp->add_online_role_id(res.online_role_list(i));
    }

    pLoginRsp->mutable_ban_data()->CopyFrom(res.role_list().role_data().ban_data());
    pLoginRsp->set_last_role_id(res.role_list().role_data().last_off_role());
    pLoginRsp->set_login_pri(pSession->GetLoginPri());

    NFPacketSendUtil::SendToClient(pSession, proto_ff::E_CS_LOGIN_RES, &oCSRsp);

    return 0;
}
